package com.ruoyi.system.service.impl;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.Month;
import java.time.ZoneId;
import java.time.temporal.WeekFields;
import java.util.*;
import java.util.stream.Collectors;

import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.system.domain.CsvData;
import com.ruoyi.system.domain.Kline;
import com.ruoyi.system.domain.vo.TechnicalIndexVo;
import com.ruoyi.system.mapper.CsvDataMapper;
import com.ruoyi.system.mapper.KlineMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import com.ruoyi.system.mapper.TechnicalIndexMapper;
import com.ruoyi.system.domain.TechnicalIndex;
import com.ruoyi.system.service.ITechnicalIndexService;

/**
 * 技术指标（年k，月k，周k）Service业务层处理
 * 
 * @author ruoyi
 * @date 2024-03-20
 */
@Service
public class TechnicalIndexServiceImpl implements ITechnicalIndexService 
{
    @Autowired
    private TechnicalIndexMapper technicalIndexMapper;
    @Autowired
    private CsvDataMapper csvDataMapper;
    @Autowired
    private KlineMapper klineMapper;
    /**
     * 查询技术指标（年k，月k，周k）
     * 
     * @param id 技术指标（年k，月k，周k）主键
     * @return 技术指标（年k，月k，周k）
     */
    @Override
    public TechnicalIndex selectTechnicalIndexById(Long id)
    {
        return technicalIndexMapper.selectTechnicalIndexById(id);
    }

    /**
     * 查询技术指标（年k，月k，周k）列表
     * 
     * @param technicalIndex 技术指标（年k，月k，周k）
     * @return 技术指标（年k，月k，周k）
     */
    @Override
    public List<TechnicalIndex> selectTechnicalIndexList(TechnicalIndex technicalIndex)
    {
        return technicalIndexMapper.selectTechnicalIndexList(technicalIndex);
    }

    /**
     * 新增技术指标（年k，月k，周k）
     * 
     * @param technicalIndex 技术指标（年k，月k，周k）
     * @return 结果
     */
    @Override
    public int insertTechnicalIndex(TechnicalIndex technicalIndex)
    {
        technicalIndex.setCreateTime(DateUtils.getNowDate());
        return technicalIndexMapper.insertTechnicalIndex(technicalIndex);
    }

    /**
     * 修改技术指标（年k，月k，周k）
     * 
     * @param technicalIndex 技术指标（年k，月k，周k）
     * @return 结果
     */
    @Override
    public int updateTechnicalIndex(TechnicalIndex technicalIndex)
    {
        technicalIndex.setUpdateTime(DateUtils.getNowDate());
        return technicalIndexMapper.updateTechnicalIndex(technicalIndex);
    }

    /**
     * 批量删除技术指标（年k，月k，周k）
     * 
     * @param ids 需要删除的技术指标（年k，月k，周k）主键
     * @return 结果
     */
    @Override
    public int deleteTechnicalIndexByIds(Long[] ids)
    {
        return technicalIndexMapper.deleteTechnicalIndexByIds(ids);
    }

    /**
     * 删除技术指标（年k，月k，周k）信息
     * 
     * @param id 技术指标（年k，月k，周k）主键
     * @return 结果
     */
    @Override
    public int deleteTechnicalIndexById(Long id)
    {
        return technicalIndexMapper.deleteTechnicalIndexById(id);
    }

    @Override
    public TechnicalIndexVo getTechnicalIndex(Long klineId,int type) {
        TechnicalIndexVo technicalIndexVo=new TechnicalIndexVo();
        //查询数据
        Kline kline = klineMapper.selectKlineById(klineId);
        TechnicalIndex query = new TechnicalIndex();
        query.setKlineType(type);
        query.setKlineId(klineId);
        List<TechnicalIndex> technicalIndices = technicalIndexMapper.selectTechnicalIndexList(query);

        //封装数据
        List<List<String>> dataList=new LinkedList<>();
        for (TechnicalIndex technicalIndex : technicalIndices) {
            List<String> rows=new LinkedList<>();
            switch (technicalIndex.getKlineType()){
                case 1:
                    rows.add(String.valueOf(technicalIndex.getKlineYear()));
                    break;
                case 2:
                    rows.add(technicalIndex.getKlineYear()+"-"+technicalIndex.getKlineMonth());
                    break;
                case 3:
                    rows.add(technicalIndex.getKlineYear()+"-"+technicalIndex.getKlineMonth()+"-"+technicalIndex.getKlineWeek());
                    break;
            }

            rows.add(String.valueOf(technicalIndex.getStartPrice().doubleValue()));
            rows.add(String.valueOf(technicalIndex.getEndPrice().doubleValue()));
            rows.add(String.valueOf(technicalIndex.getMinPrice().doubleValue()));
            rows.add(String.valueOf(technicalIndex.getMaxPrice().doubleValue()));
            rows.add(String.valueOf(technicalIndex.getTurnover()));
            dataList.add(rows);
        }
        technicalIndexVo.setkLineDataList(dataList);
        BeanUtils.copyProperties(kline,technicalIndexVo);
        return technicalIndexVo;
    }

    @Override
    @Async("threadPoolTaskExecutor")
    public void saveTechnicalIndex(Kline kline,List<CsvData> dataList) {
        List<Date> dateList = dataList.stream().map(CsvData::getTimeStamp).collect(Collectors.toList());
        //年k数据保存
        //提取所有年份
        //假设 dateList 中已经包含了多个 Date 对象
        Set<Integer> yearList = new HashSet<>();
        Set<String> yearAndMonthList = new HashSet<>();
        Set<String> yearAndMonthAndWeekList = new HashSet<>();
        for (Date date : dateList) {
            LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
            int year = localDate.getYear();
            int month = localDate.getMonth().getValue();
            int weekOfMonth = localDate.get(WeekFields.of(Locale.getDefault()).weekOfMonth());
            if (weekOfMonth==6) {
                System.out.println(date);
            }
            yearList.add(year);
            yearAndMonthList.add(year+"_"+month);
            yearAndMonthAndWeekList.add(year+"_"+month+"_"+weekOfMonth);
        }
        //根据年份保存
        for (Integer yearNumber : yearList) {
            TechnicalIndex year = new TechnicalIndex();
            year.setUserId(kline.getUserId());
            year.setKlineId(kline.getId());
            year.setKlineType(1);
            year.setKlineYear(Long.valueOf(yearNumber));
            List<CsvData> yearDataList = new ArrayList<>();
            //拿到这年的所有数据
            for (CsvData csvData : dataList) {
                LocalDate localDate = csvData.getTimeStamp().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
                int yearNum = localDate.getYear();
                if (yearNum==yearNumber.intValue()){
                    yearDataList.add(csvData);
                }
            }
            //一年的第一个交易日的开盘价
            year.setStartPrice(yearDataList.get(0).getStartPrice());
            //全年最高价
            BigDecimal maxPrice = yearDataList.stream().map(CsvData::getMaxPrice).max(BigDecimal::compareTo).get();
            year.setMaxPrice(maxPrice);
            //全年最低价
            BigDecimal minPrice = yearDataList.stream().map(CsvData::getMinPrice).min(BigDecimal::compareTo).get();
            year.setMinPrice(minPrice);
            //最后一个交易日的收盘价
            year.setEndPrice(yearDataList.get(yearDataList.size() - 1).getEndPrice());
            //全年成交量总额
            Long totalTurnover = yearDataList.stream().map(CsvData::getTurnover).reduce(0L, Long::sum);
            year.setTurnover(totalTurnover);
            year.setCreateTime(DateUtils.getNowDate());
            year.setUpdateTime(DateUtils.getNowDate());
            technicalIndexMapper.insertTechnicalIndex(year);
        }

        //月k数据保存
        //提取所有年份+月份
        //根据年份+月份保存
        for (String s : yearAndMonthList) {
            String[] split = s.split("_");
            TechnicalIndex month = new TechnicalIndex();
            month.setUserId(kline.getUserId());
            month.setKlineId(kline.getId());
            month.setKlineType(2);
            month.setKlineYear(Long.valueOf(split[0]));
            month.setKlineMonth(Long.valueOf(split[1]));
            List<CsvData> monthDataList = new ArrayList<>();
            //拿到这个月的所有数据
            for (CsvData csvData : dataList) {
                LocalDate localDate = csvData.getTimeStamp().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
                int year = localDate.getYear();
                int monthNumber = localDate.getMonth().getValue();
                if (split[0].equals(String.valueOf(year))&&split[1].equals(String.valueOf(monthNumber))){
                    monthDataList.add(csvData);
                }
            }
            //一个月的第一个交易日的开盘价
            month.setStartPrice(monthDataList.get(0).getStartPrice());
            //全月最高价
            BigDecimal maxPrice = monthDataList.stream().map(CsvData::getMaxPrice).max(BigDecimal::compareTo).get();
            month.setMaxPrice(maxPrice);
            //全月最低价
            BigDecimal minPrice = monthDataList.stream().map(CsvData::getMinPrice).min(BigDecimal::compareTo).get();
            month.setMinPrice(minPrice);
            //最后一个交易日的收盘价
            month.setEndPrice(monthDataList.get(monthDataList.size() - 1).getEndPrice());
            //全年成交量总额
            Long totalTurnover = monthDataList.stream().map(CsvData::getTurnover).reduce(0L, Long::sum);
            month.setTurnover(totalTurnover);
            month.setCreateTime(DateUtils.getNowDate());
            month.setUpdateTime(DateUtils.getNowDate());
            technicalIndexMapper.insertTechnicalIndex(month);

        }




        //周k数据保存
        //提取所有年份+月份+周份
        //根据年份+月份+周份保存
        for (String s : yearAndMonthAndWeekList) {
            String[] split = s.split("_");
            TechnicalIndex week = new TechnicalIndex();
            week.setUserId(kline.getUserId());
            week.setKlineId(kline.getId());
            week.setKlineType(3);
            week.setKlineYear(Long.valueOf(split[0]));
            week.setKlineMonth(Long.valueOf(split[1]));
            week.setKlineWeek(Long.valueOf(split[2]));
            List<CsvData> weekDataList = new ArrayList<>();
            //拿到这周的所有数据
            for (CsvData csvData : dataList) {
                LocalDate localDate = csvData.getTimeStamp().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
                int year = localDate.getYear();
                int monthNumber = localDate.getMonth().getValue();
                int weekOfMonth = localDate.get(WeekFields.of(Locale.getDefault()).weekOfMonth());
                if (split[0].equals(String.valueOf(year))&&split[1].equals(String.valueOf(monthNumber))&&split[2].equals(String.valueOf(weekOfMonth))){
                    weekDataList.add(csvData);
                }
            }
            //一个月的第一个交易日的开盘价
            week.setStartPrice(weekDataList.get(0).getStartPrice());
            //全月最高价
            BigDecimal maxPrice = weekDataList.stream().map(CsvData::getMaxPrice).max(BigDecimal::compareTo).get();
            week.setMaxPrice(maxPrice);
            //全月最低价
            BigDecimal minPrice = weekDataList.stream().map(CsvData::getMinPrice).min(BigDecimal::compareTo).get();
            week.setMinPrice(minPrice);
            //最后一个交易日的收盘价
            week.setEndPrice(weekDataList.get(weekDataList.size() - 1).getEndPrice());
            //全年成交量总额
            Long totalTurnover = weekDataList.stream().map(CsvData::getTurnover).reduce(0L, Long::sum);
            week.setTurnover(totalTurnover);
            week.setCreateTime(DateUtils.getNowDate());
            week.setUpdateTime(DateUtils.getNowDate());
            technicalIndexMapper.insertTechnicalIndex(week);

        }



    }
}
